#pragma once
#include "map.h"
#include <deque>
class UpdatePotPhase: public GamePhase
{
private:
	Map m_menu;
	Game * g;	//A pointer to the game object
	bool hasBeenShuffled;
	deque<Bill*> fiveThou;
	deque<Bill*> tenThou;
	deque<Bill*> twentyThou;
	int splitBetween;
public:
	UpdatePotPhase(char * a_filename, Game * a_game)
	{
		m_menu.loadFile(a_filename);
		g = a_game;
		hasBeenShuffled = false;
		splitBetween = 0;
	}

	void update(int a_ms)
	{
		if (g->getState() == NEW_POT)	//We need to get a new pot
		{
			if (!hasBeenShuffled)
			{
				shuffle();
				hasBeenShuffled = true;
			}
			g->thePot.update();
			switch(returnInput())
			{
			case ' ':
				{
					undraw();
					g->setState(ACTION_SELECTION);
					break;
				}
			}
			getInput(0);
		}

		else if (g->getState() == SPLIT_THE_POT)  //We need to split the money of the current pot.
		{
			//Get the number of players in the split
			for (int i = 0; i < MAX_PLAYERS; ++i)
			{
				if (g->getPlayer(i)->isInTheSplit())
				{
					splitBetween++;
				}
			}

			//Look at all the bills in the pot, and push them onto their respective stacks
		//	if (g->thePot.currentPot.size() >= (unsigned)g->thePot.getpotSize())
		//	{
			for (int j = 0; j < (signed)g->thePot.currentPot.size(); j++)
				{
					switch (g->thePot.currentPot[j]->value)
					{
					case 5000:
						fiveThou.push_front(g->thePot.currentPot[j]);
						break;
					case 10000:
						tenThou.push_front(g->thePot.currentPot[j]);
						break;
					case 20000:
						twentyThou.push_front(g->thePot.currentPot[j]);
						break;
					default: break;
					}
				}
				for (int j = 0; j < g->thePot.getpotSize(); j++)
				{
					g->thePot.currentPot.pop_front();
				}
		//	}
			g->thePot.potSize = 0;	//The pot should now be empty
			g->thePot.potLoaded = false;	//Set a flag to remember to refill the pot next NEW_POT phase.

			//Starting at 20,000 and counting down to 5,000, see if the money can be split into even amounts of that amount.
			for (int amount = 20000; amount >= 5000; amount -= 5000)
			{
				bool canSplit = false;
				int splitOne, splitTwo, splitThree, splitFour;
				switch (amount)
				{
				case 5000:
					if ((signed)fiveThou.size() >= splitBetween)
					{
						for (int i = 0; i < MAX_PLAYERS; i++)	//Loop through the players
						{
							if (g->getPlayer(i)->isInTheSplit())	//If it is a player that can take part in this split.
							{
								g->getPlayer(i)->pay(amount);	
							}
						}
						for (int i = 0; i < splitBetween; i++)
						{
							fiveThou.pop_front();
						}
						amount = 25000;
					}
					break;
				case 10000:
					splitOne = 0;
					splitTwo = 0;
					for (int j = 0; j < splitBetween; j++)//See the number of people we need to split between
					{

						if ((signed)fiveThou.size() >= 2 + 2*splitOne)	//See if it can be split by "Simulating" a split.
						{
							canSplit = true;
							splitOne++;
						}
						else if ((signed)tenThou.size() >= 1 + splitTwo)
						{
							canSplit = true;
							splitTwo++;
						}
						else
						{
							canSplit = false;
						}
					}
					if (canSplit)
					{
						//Pay the appropriate players
						for (int i = 0; i < MAX_PLAYERS; i ++)
						{
							if (g->getPlayer(i)->isInTheSplit())
							{
								g->getPlayer(i)->pay(amount);
							}
						}
						//Get rid of the money that was paid out
						for (int i = 0; i < splitBetween; i++)
						{
							if (tenThou.size() >= 1) 
							{
								tenThou.pop_front();
							}
							else if (fiveThou.size() >= 2)
							{
								fiveThou.pop_front();
								fiveThou.pop_front();
							}

						}
						amount = 25000;
					}
					canSplit = false;
					break;
				case 15000:
					splitOne = 0;
					splitTwo = 0;
					for (int j = 0; j < splitBetween; j++)//See the number of people we need to split between
					{
						if ((signed)fiveThou.size() >= 3 + (3*splitOne)) //See if it can be split by "Simulating" a split.		
						{
							canSplit = true;
							splitOne++;
						}
						else if  ((signed)tenThou.size() >= 1 + j && (signed)fiveThou.size() >= 1 + j)
						{
							canSplit = true;
							splitTwo++;
						}
						else
						{
							canSplit = false;
						}
					}
					if (canSplit)
					{
						//Pay the appropriate players
						for (int i = 0; i < MAX_PLAYERS; i ++)
						{
							if (g->getPlayer(i)->isInTheSplit())
							{
								g->getPlayer(i)->pay(amount);
							}
						}
						//Get rid of the money that was paid out
						for (int i = 0; i < splitBetween; i++)
						{
							if (tenThou.size() >= 1 && fiveThou.size() >= 1) 
							{
								tenThou.pop_front();
								fiveThou.pop_front();
							}
							else if (fiveThou.size() >= 3)
							{
								fiveThou.pop_front();
								fiveThou.pop_front();
								fiveThou.pop_front();
							}
							
						}
						amount = 25000;
					}
					canSplit = false;
					break;
				case 20000:
					splitOne = 0;
					splitTwo = 0;
					splitThree = 0;
					splitFour = 0;
					for (int j = 0; j < splitBetween; j++)//See the number of people we need to split between
					{
						if ((signed)fiveThou.size() >= 4 + (4*splitOne))  	//See if it can be split by "Simulating" a split.
						{
							canSplit = true;
							splitOne++;
						}
						else if ((signed)tenThou.size() >= 2 + (2*splitTwo))
						{
							canSplit = true;
							splitTwo++;
						}
						else if ((signed)tenThou.size() >= 1 + splitThree && (signed)fiveThou.size() >= 2 + (2*splitTwo))
						{
							canSplit = true;
							splitThree++;
						}
						else if ((signed)twentyThou.size() >= 1 + splitFour)
						{
							canSplit = true;
							splitFour++;
						}
						else
						{
							canSplit = false;
						}
					}
					if (canSplit)
					{
						//Pay the appropriate players
						for (int i = 0; i < MAX_PLAYERS; i ++)
						{
							if (g->getPlayer(i)->isInTheSplit())
							{
								g->getPlayer(i)->pay(amount);
							}
						}
						//Get rid of the money that was paid out
						for (int i = 0; i < splitBetween; i++)
						{
							if (twentyThou.size() >= 1)
							{
								twentyThou.pop_front();
							}
							else if (tenThou.size() >= 2)
							{
								tenThou.pop_front();
								tenThou.pop_front();
							}
							else if (tenThou.size() >= 1 && fiveThou.size() >= 2) 
							{
								tenThou.pop_front();
								fiveThou.pop_front();
								fiveThou.pop_front();
							}
							else if (fiveThou.size() >= 4)
							{
								fiveThou.pop_front();
								fiveThou.pop_front();
								fiveThou.pop_front();
								fiveThou.pop_front();
							}	
						}
						amount = 25000;
					}
					canSplit = false;
					break;
				default: break;
				}
			}
			//If the total pool of money is empty at this point, it is time to check who won!
			if (g->thePot.cash.empty())
			{
				Player * winner = NULL;
				for (int i = 0; i < MAX_PLAYERS; i++)
				{
					//They can't be dead
					if (g->getPlayer(i)->getHealth() > 0)
					{
						if (winner == NULL)	//If they are the first to be checked, then this is good enough.
						{
							winner = g->getPlayer(i);
						}
						else	//Check to see which has the most money, after shame is taken out.
						{
							int endGameTotal = g->getPlayer(i)->getCash() - (5000 * g->getPlayer(i)->getShame());
							int winnersTotal = winner->getCash() - (5000 * winner->getShame());

							if (endGameTotal > winnersTotal)  //The winner is the one with the most money still
							{
								winner = g->getPlayer(i);
							}
						}
					}
				}
				printf(" %s is the winner, with a total of $%d.00!", winner->name, winner->getCash() - (5000 * winner->getShame()));
				_getch();
				g->running = false;
			}
			//At this point, all the money has been split.  Time to put any unsplit money back on the stack.
			while (!fiveThou.empty())
			{
				g->thePot.currentPot.push_front(fiveThou.front());
				fiveThou.pop_front();
			}
			while (!tenThou.empty())
			{
				g->thePot.currentPot.push_front(tenThou.front());
				tenThou.pop_front();
			}
			while (!twentyThou.empty())
			{
				g->thePot.currentPot.push_front(twentyThou.front());
				twentyThou.pop_front();
			}
			//All players that were out of the split are now eligible again
			for (int i = 0; i < MAX_PLAYERS; i++)
			{
				g->getPlayer(i)->takePartInSplit = true;
			}
			//Remember to set splitBetween back to 0 before splitting again
			splitBetween = 0;
			//Increase the size of the pot before it is revealed next phase
			g->thePot.potSize = 5 + g->thePot.currentPot.size();
			g->thePot.potLoaded = false;
			g->thePot.update();
			//Also, go IMMEDIATELY to the next phase, so this doesn't update multiple times.
			g->setState(NEW_POT);
			//g->setState(ACTION_SELECTION);

		}
		getInput(0);
	}
	void draw()
	{
		if (g->getState() == NEW_POT && g->isRunning())		//Only draw the new pot phase, and only while the game hasn't ended.  Split the pot can happen behind the scenes.
		{
			if (hasBeenShuffled)
			{
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
				m_menu.draw(0,0);
				g->thePot.draw();
			}
		}
	}

	void undraw()
	{
		m_menu.undraw();
	}

	void shuffle()
	{
		g->thePot.shuffle();
	}
};